package com.shunli.cterminal.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.examples.core.exception.ServiceException;
import com.shunli.cterminal.model.code.CterminalResultCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName: OrderNoService
 * @Description: TODO
 * @Author: DAIYALU
 * @Date: 2025/4/25
 * @Version: 1.0
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderNoService {

    private final RedissonClient redissonClient;

    /**
     * 返回14位数字字符串
     * @return
     */
    public String queryOrderNo(){
        Thread thread = Thread.currentThread();
        log.info("【分布式锁】获取锁，线程ID:{},线程名称:{}", thread.getId(), thread.getName());
        RLock lock = redissonClient.getLock("onlineOrderNo");
        try {
            boolean isLock = lock.tryLock(3, 5, TimeUnit.SECONDS);
            if (isLock) {
                String now = DateUtil.format(LocalDateTime.now(), "MMddHHmmss");
                RBucket<String> bucket = redissonClient.getBucket("online_order_no:" + now);
                String orderNo = bucket.get();
                if (StrUtil.isNotBlank(orderNo)) {
                    log.info("queryOrderNo,redis orderNo:{}", orderNo);
                    //数值加1防重
                    orderNo = String.valueOf(Long.parseLong(orderNo) + 1);
                    bucket.set(orderNo, 60, TimeUnit.SECONDS);
                    if(orderNo.length() < 13){
                        log.info("补位 orderNo:{}", orderNo);
                        //少于13位，左边补位字符串"0"
                        orderNo = "0" + orderNo;
                    }
                    //拼接长度
                    return orderNo+1;
                }
                orderNo = now + RandomUtil.randomInt(100,700);
                bucket.set(orderNo, 60, TimeUnit.SECONDS);
                //拼接长度
                return orderNo + 1;
            }else {
                throw new ServiceException(CterminalResultCode.H5_ORDER_NO_BUILD_FAIL);
            }
        }catch (InterruptedException e) {
            if (lock.isHeldByCurrentThread() && lock.isLocked()) {
                lock.unlock();
            }
        }finally {
            if (lock.isHeldByCurrentThread() && lock.isLocked()) {
                lock.unlock();
            }
        }
        throw new ServiceException(CterminalResultCode.H5_ORDER_NO_BUILD_FAIL);
    }
}
